package utils

import (
	"encoding/json"
	"fmt"
	"os"
	"path"
	"time"
)

func ReportExecuteTime(name string, f func()) {
	begin := time.Now()
	f()
	end := time.Now()
	duration := end.Sub(begin)
	fmt.Printf("Execution time for %s took %s\n", name, duration)
}

type BenchmarkResult struct {
	// ExecuteTime in milliseconds
	ExecuteTime  float64 `json:"execute_time"`
	ExecuteCount int     `json:"execute_count"`
	AverageTime  float64 `json:"average_time"`
}

func runOne(f func()) float64 {
	begin := time.Now()
	f()
	end := time.Now()
	duration := end.Sub(begin)
	// get milliseconds
	return float64(duration.Microseconds()) / 1000
}

func ReportBenchmarkJSON(reportDir, name string, f func(), sleepTime time.Duration, count int) {
	jsonFile := path.Join(reportDir, name+".json")

	result := &BenchmarkResult{}
	oldFile, err := os.Open(jsonFile)
	if err == nil {
		_ = json.NewDecoder(oldFile).Decode(result)
	}

	file, err := os.Create(jsonFile)
	if err != nil {
		panic(err)
	}

	executeTime := float64(0)
	for i := 0; i < count; i++ {
		if i > 0 {
			time.Sleep(sleepTime)
		}
		executeTime += runOne(f)
	}

	result.ExecuteTime += executeTime
	result.ExecuteCount += count
	result.AverageTime += executeTime / float64(count)
	data, _ := json.Marshal(result)
	_, err = file.Write(data)
	if err != nil {
		panic(err)
	}
}
